#include<iostream>
#include<queue>
#include<mutex>
#include<pthread.h>
#include"LockGuard.hpp"

const int gDefaultCap=5;
template <class T>
class BlockQueue
{
private:
    bool isQueueEmpty(){
        return _bq.size==0;
    }
    bool isQueueFull(){
        return _bq.size==_capacity;
    }
public:
    BlockQueue(int capacity=gDefaultCap)
    :_capacity(capacity)
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_full,nullptr);
        pthread_cond_init(&_empty,nullptr);
    }
    void push(const T& in)
    {
        LockGuard lockguard(&_mutex);
        while(isQueueFull()){
            pthread_cond_wait(&_full,&_mutex);
        }
        _bq.push(in);
        pthread_cond_signal(&_empty);
    }
    //这里调用的是输出型参数
    void pop(T* out)
    {
        LockGuard lockguard(&_mutex);
        while(isQueueEmpty()){
            pthread_cond_wait(&_empty,&_mutex);
        }
        *out=_bq.front();
        _bq.pop();
        pthread_cond_signal(&_full);
    }
    ~BlockQueue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_full);
        pthread_cond_destroy(&_empty);
    }
private:
    std::queue<T> _bq;
    int _capacity;
    pthread_mutex_t _mutex;
    pthread_cond_t _full;
    pthread_cond_t _empty;
};

// const int gDefaultCap=5;

// template <class T>
// class BlockQueue
// {
// public: 
//     BLockQueue(int capacity=gDefaultCap)
//     :_capacity(capacity)
//     {
//         pthread_mutex_init(&_mutex,nullptr);
//         pthread_cond_init(&_empty,nullptr);
//         pthread_cond_init(&_full,nullptr);
//     }
//     void push(const T& in){
//         LockGuard lockguard(&_mutex);
//         while(isQueueFull()){
//             pthread_cond_wait(&_full,&_mutex);
//         }
//         _bq.push(in);
//         pthread_cond_signal(&_empty);
//     }
//     void pop()
//     {
//         LockGuard lockguard(&_mutex);
//         while(isQueueEmpty()){
//             pthread_cond_wait(&_full,&_mutex);
//         }
//         *out=_bq.front();
//         _bq.pop();
//         pthread_cond_signal(&_full);
//     }
//     void push(const T& in)
//     {
//         LockGuard lockguard(_mutex);
//         while(isQueueFull())
//         {
//             //这里不满足条件就阻塞在这里等待
//             pthread_cond_wait(&_full,&_mutex);
//         }
//         _bq.push(in);
//         //通知正在阻塞的进程判断是否满足了条件，负责继续
//         //等待
//         //如果还空的话那么就可以添加任务了
//         pthread_cond_signal(&_empty);
//     }
//     void pop(T* out)
//     {
//         lockGuard lockguard(_mutex);
//         while(isQueueEmpty()){
//             pthread_cond_wait(&_empty,&_mutex);
//         }
//         *out=_bq.front();
//         _bq.pop();
//         pthread_cond_signal(&_full);
//     }
//     //销毁的时候讲锁和条件变量全部释放掉
//     ~BlockQueue(){
//         pthread_mutex_destroy(&_mutex);
//         pthread_cond_destroy(&_empty);
//         pthread_cond_destroy(&_full);
//     }
// private:
//     bool isQueueEmpty(){
//         return _bq.size()==0;
//     }
//     bool isQueueFull(){
//         return _bq.size()==_capaicty;
//     }

//     std::queue<T> _bq;
//     int _capacity;
//     pthread_mutex_t _mutex;
//     pthread_cond_t _empty;
//     pthread_cond_t _full;
// };